/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

/**
 * 广告位展示列表
 *  */
import React, { useCallback, useState, useEffect } from "react";
import PropTypes from "prop-types";
import { Col, Form, Input, Modal, Radio, Row, message, Select, Icon } from "antd";
import { connect } from "dva";
import { spliceURL } from "@/utils/patterns";
import styles from "./AdvAdd.less";
import UploadWithCrypto from "@/components/upload-width-crypto";

const WARN_TEXT =
  "注：此处为点击图片打开小程序路径指定的页面，请不要设置淘宝客相关链接及违反公众号不允许的营销链接，会有封号风险，小程序平台不支持跳转h5连接(公众号连接除外)。";

const RadioGroup = Radio.Group;
const FormItem = Form.Item;
const { Option } = Select;
const noop = () => {};

const SelectBefore = ({ onChange, urlType = "https://" }) => (
  <Select onChange={onChange} defaultValue={urlType} style={{ width: 90 }}>
    <Option value="http://">http://</Option>
    <Option value="https://">https://</Option>
  </Select>
);

const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 4 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 19 },
  },
};

const formConfig = {
  miniApp: [
    {
      label: "小程序ID",
      key: "app_id",
      rules: [
        {
          required: true,
          message: "请输入小程序ID",
        },
      ],
      placeholder: "如：wx123456789",
    },
    {
      label: "原始ID",
      key: "original_id",
      rules: [
        {
          required: true,
          message: "请输入小程序原始ID",
        },
      ],
      placeholder: "如：gh_123456789",
    },
    {
      label: "小程序路径",
      key: "advertising_url",
      rules: [
        {
          required: true,
          message: "请输入小程序路径",
        },
      ],
      placeholder: "如：pages/index/index",
      help: WARN_TEXT,
    },
  ],
  h5: [
    {
      label: "h5链接",
      key: "advertising_url",
      AddonBefore: ({ onChange, urlType }) => (
        <SelectBefore onChange={onChange} urlType={urlType} />
      ),
      rules: [
        {
          required: true,
          message: "请输入小程序路径",
        },
      ],
      placeholder: "如：mp.weixin.qq.com",
      help: WARN_TEXT,
    },
  ],
};

const channelMap = {
  "1": "miniApp",
  "2": "h5",
};

const AdvAdd = ({
  type,
  visible,
  form,
  record = {},
  dispatch,
  getList = noop,
  onVisibleChange = noop,
  ...rest
}) => {
  const { url_type = "1", image_url, id } = record;
  const { getFieldDecorator, validateFields, isFieldsTouched, resetFields } = form;

  const [channel, setChannel] = useState("miniApp");
  const [imgUrl, setImgUrl] = useState(image_url);
  const [httpType, setHttpType] = useState("https://");

  useEffect(
    () => {
      if (visible) {
        setChannel(channelMap[url_type]);
      }
      // 修改时，初始化上传图片
      setImgUrl(visible ? image_url : "");
      return () => {
        resetFields();
      };
    },
    [url_type, image_url, visible, resetFields]
  );

  const getFormValue = useCallback(
    (cb = noop) => {
      const isAdd = type === "add";
      const fields = ["url_type", "advertising_url"];
      // 防止多余的校验
      if (channel == "miniApp") {
        fields.push("app_id");
        fields.push("original_id");
      }
      // 新增广告时，再去校验是否上传图片
      if (isAdd) {
        fields.push("image_url");
      }
      validateFields(fields, (err, values) => {
        if (err) return;
        const { image_url: uploadFile = [], advertising_url, ...rests } = values;
        const { file = {} } = uploadFile[0] || {};
        const { response: { data } = {} } = file;
        let url = advertising_url;
        const urlBody = spliceURL(advertising_url, "body");

        if (channel == "h5") {
          url = `${httpType}${urlBody}`;
        }

        cb({
          ...rests,
          advertising_url: url,
          image_url: data || imgUrl,
          id: !isAdd ? id : undefined,
        });
      });
    },
    [validateFields, channel, type, imgUrl, id, httpType]
  );

  const onOk = useCallback(
    () => {
      const isTouched = isFieldsTouched([
        "url_type",
        "image_url",
        "app_id",
        "original_id",
        "advertising_url",
      ]);
      // 编辑时校验字段是否更新过
      if (!isTouched && type === "edit") {
        onVisibleChange(false);
        return;
      }
      const effects = type === "add" ? "wxSettings/addAdv" : "wxSettings/editAdv";
      getFormValue(values => {
        dispatch({
          type: effects,
          payload: {
            ...values,
          },
        }).then(() => {
          getList();
          onVisibleChange(false);
        });
      });
    },
    [onVisibleChange, getFormValue, isFieldsTouched, dispatch, getList, type]
  );

  const onCancel = useCallback(
    () => {
      onVisibleChange(false);
    },
    [onVisibleChange]
  );

  const onRadioChange = useCallback(
    e => {
      const { names } = e.target;
      setChannel(names);
      resetFields();
    },
    [resetFields]
  );

  // 上传相关功能
  const normFile = e => {
    const { file } = e;
    // 上传前的校验
    const isLt200kb = file.size / 1024 <= 200;
    if (!isLt200kb) {
      message.error("只能上传200KB以内的图片！");
      setImgUrl("");
      return [];
    }
    // 设置上传后的图片地址
    if (file.status == "done") {
      const { response = {} } = file;
      if (response.code == 0) {
        setImgUrl(response.data);
      } else {
        message.error(response.msg);
        return [];
      }
    }
    // 只返回最新上传的图片
    return e && [file];
  };

  const onURLChange = value => {
    setHttpType(value);
  };

  return (
    <Modal
      width={900}
      centered
      destroyOnClose
      title={type === "add" ? "新建广告" : "修改广告"}
      onOk={onOk}
      onCancel={onCancel}
      visible={visible}
      {...rest}
    >
      <Form layout="horizontal" {...formItemLayout}>
        <FormItem label="跳转连接">
          {getFieldDecorator("url_type", {
            initialValue: url_type || "1",
            rules: [
              {
                required: true,
                message: "请选择跳转连接",
              },
            ],
          })(
            <RadioGroup onChange={onRadioChange}>
              <Radio value="1" names="miniApp">
                小程序
              </Radio>
              <Radio value="2" names="h5">
                h5链接
              </Radio>
            </RadioGroup>
          )}
        </FormItem>
        {formConfig[channel].map(({ label, key, rules, placeholder, help, AddonBefore }) => {
          const protocol = channel == "h5" ? spliceURL(record[key], "protocol") : undefined;
          const initialValue = channel == "h5" ? spliceURL(record[key], "body") : record[key];
          return (
            <FormItem key={key} label={label} help={help}>
              {getFieldDecorator(key, {
                initialValue,
                rules,
              })(
                <Input
                  addonBefore={
                    AddonBefore ? <AddonBefore onChange={onURLChange} urlType={protocol} /> : null
                  }
                  placeholder={placeholder}
                />
              )}
            </FormItem>
          );
        })}
        <FormItem label="广告图片">
          <Row>
            <Col>（注：图片尺寸：710*140像素，格式：jpg、png或jpeg，大小：不超过200kb）</Col>
            <Col>
              {getFieldDecorator("image_url", {
                valuePropName: "fileList",
                getValueFromEvent: normFile,
                rules: [
                  {
                    required: true,
                    message: "请上传广告图片！",
                  },
                ],
              })(
                <UploadWithCrypto
                  style={{ width: 710, height: 140 }}
                  listType="picture-card"
                  className={styles["avatar-uploader"]}
                  name="img"
                  action="/Api/Advertising/uploadImage"
                  accept="image/png,image/jpg,image/jpeg"
                  showUploadList={false}
                >
                  {imgUrl ? (
                    <img alt="" src={imgUrl} style={{ width: 710, height: 140 }} />
                  ) : (
                    <div>
                      <Icon type="plus" />
                      <div className="ant-upload-text">上传图片</div>
                    </div>
                  )}
                </UploadWithCrypto>
              )}
            </Col>
          </Row>
        </FormItem>
      </Form>
    </Modal>
  );
};

AdvAdd.defaultProps = {
  record: {},
};

AdvAdd.propTypes = {
  type: PropTypes.oneOf(["add", "edit"]).isRequired,
  visible: PropTypes.bool.isRequired,
  getList: PropTypes.func.isRequired,
  record: PropTypes.object,
  onVisibleChange: PropTypes.func.isRequired,
};

export default connect()(React.memo(Form.create()(AdvAdd)));
